package br.ufpe.cin.mac.parser.xml;

import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import br.ufpe.cin.mac.parser.Binds;
import br.ufpe.cin.mac.parser.CanonicalElements;
import br.ufpe.cin.mac.parser.XBind;
import br.ufpe.cin.mac.parser.XComponent;
import br.ufpe.cin.mac.parser.XConnector;
import br.ufpe.cin.mac.parser.XMiddleware;

public class XmlReader {

	private XMiddleware mid;

	private SAXBuilder sb;

	public XmlReader() {
		sb = new SAXBuilder();
	}

	public XMiddleware readXml(String file) {
		try {
			Document doc = sb.build(file);
			Element xMiddleware = doc.getRootElement();

			mid = readXMiddleware(xMiddleware);

			return mid;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public XMiddleware getXMiddleware() {
		return mid;
	}

	private XMiddleware readXMiddleware(Element xMiddleware) {
		XMiddleware mid = new XMiddleware(xMiddleware.getAttributeValue("id"));
		mid.setType(xMiddleware.getAttributeValue("type"));
		Element canonical = xMiddleware.getChild(CanonicalElements.TAG_NAME);
		mid.setCanonicalElements(readCanonicalElements(canonical));

		Element binds = xMiddleware.getChild(Binds.tagName);
		mid.setBinds(readBinds(binds));

		return mid;
	}

	private CanonicalElements readCanonicalElements(Element can) {
		CanonicalElements canonical = new CanonicalElements();

		List<Element> xComps = can.getChildren(XComponent.tagName);
		Iterator<Element> iComp = xComps.iterator();

		while (iComp.hasNext()) {
			Element comp = iComp.next();

			canonical.addXComponent(new XComponent(
					comp.getAttributeValue("id"), comp
							.getAttributeValue("name")));
		}

		List<Element> xConns = can.getChildren(XConnector.TAG_NAME);
		Iterator<Element> iConn = xConns.iterator();

		while (iConn.hasNext()) {
			Element conn = iConn.next();
			
			canonical.addXConnector(new XConnector(
					conn.getAttributeValue("id"), conn
							.getAttributeValue("name")));

		}
		// Leitura do Connector Concretor
		List<Element> concrete = can.getChildren(XConnector.TAG_NAME_CONCRETE);
		canonical.addConcreteConnector(new XConnector(concrete.get(0)
				.getAttributeValue("id"), concrete.get(0).getAttributeValue(
				"name")));
				
		return canonical;
	}

	private Binds readBinds(Element b) {
		Binds binds = new Binds();

		List<Element> xBinds = b.getChildren(XBind.tagName);

		Iterator<Element> iBind = xBinds.iterator();

		while (iBind.hasNext()) {

			Element bind = iBind.next();

			binds.addBind(new XBind(bind.getAttributeValue("id"), bind
					.getAttributeValue("from"), bind.getAttributeValue("to"),
					bind.getAttributeValue("through")));

		}

		return binds;
	}
}
